package repository

import (
	"fmt"
	"strings"
	"whale/internal/load"
	"whale/pkg/utils"

	"xorm.io/xorm"
)

// genertar r *Repository  IRepository
type IRepository interface {
	// 表名
	Table(table interface{}) *Repository
	// 查询条件
	Where(conditions ...interface{}) *Repository
	// Like查询
	LikeSearch(fields []string, value string) *Repository
	// BETWEEN 时间区间查询
	Bentween(field string, startTime, endTime string) *Repository
	// 判断字符串相等
	Eq(field string, value interface{}) *Repository
	// 更新时忽略某个字段
	Omit(field ...string) *Repository
	// 更新时只更新某个字段
	Cols(field ...string) *Repository
	// 返回数据对象
	GetSession() *xorm.Session
	// 排序
	OrderBy(order interface{}, args ...interface{}) *Repository
	// 分页
	Paging(page, pageSize int) *Repository
	// 查询列表
	GetList(dest interface{}) error
	// 查询单条数据
	Get(dest interface{}) (bool, error)
	// 新增
	Insert(dest interface{}) error
	// 更新
	Update(dest interface{}) error
	// 判断数据是否存在 存在true 不存在false
	Exits() bool
	// 删除数据
	Deleted() error
}

// 表名
func (r *Repository) Table(table interface{}) *Repository {
	r.session = r.DB.Dao().NewSession()
	r.session.Table(table)
	return r
}

// Like查询
func (r *Repository) LikeSearch(fields []string, value string) *Repository {
	if utils.IsNotEmpty(value) {
		var params []interface{}
		var conditions []string
		for _, v := range fields {
			conditions = append(conditions, fmt.Sprintf("`%s` like ? ", v))
			params = append(params, fmt.Sprintf("%%%s%%", value))
		}
		r.session.Where(strings.Join(conditions, " or "), params...)
	}
	return r
}

func (r *Repository) Eq(field string, value interface{}) *Repository {
	if value, ok := value.(int); ok {
		if value > 0 {
			r.Where(fmt.Sprintf("`%s` = ?", field), value)
		}
	}
	if value, ok := value.(string); ok {
		if utils.IsNotEmpty(value) {
			r.Where(fmt.Sprintf("`%s` = ?", field), value)
		}
	}
	return r
}

// BETWEEN 时间区间查询
func (r *Repository) Bentween(field string, startTime, endTime string) *Repository {
	if utils.IsNotEmpty(startTime) && utils.IsNotEmpty(endTime) {
		r.session.Where(fmt.Sprintf("%s BETWEEN ? AND ?", field), startTime, endTime)
	}
	return r
}

// 排序
func (r *Repository) OrderBy(order interface{}, args ...interface{}) *Repository {
	r.session.OrderBy(order, args...)
	return r
}

// 分页
func (r *Repository) Paging(page, pageSize int) *Repository {
	r.session.Limit(pageSize, (page-1)*pageSize)
	return r
}

// 返回事务对象
func (r *Repository) GetSession() *xorm.Session {
	return r.session
}

// 查询条件
func (r *Repository) Where(conditions ...interface{}) *Repository {
	if len(conditions) > 0 {
		r.session.Where(conditions[0], conditions[1:]...)
	}
	return r
}

// 更新时忽略某个字段
func (r *Repository) Omit(field ...string) *Repository {
	r.session.Omit(field...)
	return r
}

// 更新时 只更新某个字段
func (r *Repository) Cols(field ...string) *Repository {
	r.session.Cols(field...)
	return r
}

// 查询列表
func (r *Repository) GetList(dest interface{}) error {
	defer r.session.Close()
	r.session.Engine().ShowSQL()
	return r.session.Find(dest)
}

// 查询单条数据
func (r *Repository) Get(dest interface{}) (bool, error) {
	defer r.session.Close()
	r.session.Engine().ShowSQL()
	return r.session.Get(dest)
}

func (r *Repository) Insert(dest interface{}) error {
	defer r.session.Close()
	_, err := r.session.Insert(dest)
	r.session.Engine().ShowSQL()
	return err
}

func (r *Repository) Update(dest interface{}) error {
	defer r.session.Close()
	_, err := r.session.Update(dest)
	r.session.Engine().ShowSQL()
	return err
}

func (r *Repository) Deleted() error {
	defer r.session.Close()
	_, err := r.session.Delete()
	r.session.Engine().ShowSQL()
	return err
}

func (r *Repository) Exits() bool {
	defer r.session.Close()
	ok, _ := r.session.Exist()
	r.session.Engine().ShowSQL()
	return ok
}

type Repository struct {
	session *xorm.Session
	DB      load.IDBConnect `bean:"DBConnect"`
}
